const fs = require('fs-extra');
const path = require('path');
const mime = require('mime-types');
const config = require('../config');
const { validatePath, safePath, sanitizeFilename } = require('../utils');

class FileController {
  // 获取文件列表
  static async getFiles(ctx) {
    const relativePath = ctx.query.path || '';
    
    if (!validatePath(relativePath)) {
      ctx.throw(400, '非法路径');
    }
    
    // 安全路径构建
    const { path: fullPath, safe } = safePath(config.storage.path, relativePath);
    if (!safe) {
      ctx.throw(400, '无效的路径');
    }
    
    try {
      const stats = await fs.stat(fullPath);
      if (!stats.isDirectory()) {
        ctx.throw(400, '指定路径不是目录');
      }
      
      const items = await fs.readdir(fullPath);
      const files = [];
      
      for (const item of items) {
        const itemPath = path.join(fullPath, item);
        const itemStats = await fs.stat(itemPath);
        
        files.push({
          name: item,
          path: path.join(relativePath, item).replace(/\\/g, '/'),
          type: itemStats.isDirectory() ? 'folder' : 'file',
          size: itemStats.isDirectory() ? 0 : itemStats.size,
          modified: itemStats.mtime,
          mimeType: itemStats.isDirectory() ? null : mime.lookup(item) || 'application/octet-stream'
        });
      }
      
      // 按类型排序（文件夹在前）再按名称排序
      files.sort((a, b) => {
        if (a.type !== b.type) {
          return a.type === 'folder' ? -1 : 1;
        }
        return a.name.localeCompare(b.name, 'zh-CN');
      });
      
      ctx.body = {
        success: true,
        data: {
          path: relativePath,
          files: files
        }
      };
    } catch (err) {
      ctx.throw(500, `读取目录失败: ${err.message}`);
    }
  }

  // 创建文件夹
  static async createFolder(ctx) {
    const { name, path: relativePath } = ctx.request.body;
    
    if (!name) {
      ctx.throw(400, '文件夹名称不能为空');
    }
    
    if (!validatePath(relativePath || '')) {
      ctx.throw(400, '非法路径');
    }
    
    // 清理文件夹名称，防止路径遍历攻击
    const safeFolderName = sanitizeFilename(name);
    if (!safeFolderName || safeFolderName === 'unnamed_file') {
      ctx.throw(400, '文件夹名称无效');
    }
    
    // 安全路径构建
    const { path: basePath, safe } = safePath(config.storage.path, relativePath || '');
    if (!safe) {
      ctx.throw(400, '无效的路径');
    }
    
    const folderPath = path.join(basePath, safeFolderName);
    
    try {
      await fs.ensureDir(folderPath);
      ctx.body = {
        success: true,
        message: '文件夹创建成功',
        data: {
          name: safeFolderName,
          path: relativePath ? path.join(relativePath, safeFolderName).replace(/\\/g, '/') : safeFolderName
        }
      };
    } catch (err) {
      ctx.throw(500, `创建文件夹失败: ${err.message}`);
    }
  }

  // 删除文件或文件夹
  static async deleteFiles(ctx) {
    const { paths } = ctx.request.body;
    
    if (!paths || !Array.isArray(paths)) {
      ctx.throw(400, '请提供要删除的文件路径');
    }
    
    try {
      const deletedFiles = [];
      const failedFiles = [];
      
      for (const relativePath of paths) {
        if (!validatePath(relativePath)) {
          failedFiles.push(relativePath);
          continue;
        }
        
        // 安全路径构建
        const { path: fullPath, safe } = safePath(config.storage.path, relativePath);
        if (!safe) {
          failedFiles.push(relativePath);
          continue;
        }
        
        try {
          await fs.remove(fullPath);
          deletedFiles.push(relativePath);
        } catch (err) {
          failedFiles.push(relativePath);
        }
      }
      
      if (deletedFiles.length === 0) {
        ctx.throw(500, '所有文件删除失败');
      }
      
      let message = `成功删除 ${deletedFiles.length} 个文件`;
      if (failedFiles.length > 0) {
        message += `，${failedFiles.length} 个文件删除失败`;
      }
      
      ctx.body = {
        success: true,
        message: message,
        data: {
          deletedFiles: deletedFiles,
          failedFiles: failedFiles
        }
      };
    } catch (err) {
      ctx.throw(500, `删除失败: ${err.message}`);
    }
  }

  // 下载文件
  static async downloadFile(ctx) {
    const relativePath = ctx.query.path;
    
    if (!relativePath) {
      ctx.throw(400, '请指定下载文件路径');
    }
    
    if (!validatePath(relativePath)) {
      ctx.throw(400, '非法路径');
    }
    
    // 安全路径构建
    const { path: fullPath, safe } = safePath(config.storage.path, relativePath);
    if (!safe) {
      ctx.throw(400, '无效的路径');
    }
    
    try {
      const stats = await fs.stat(fullPath);
      
      if (stats.isDirectory()) {
        ctx.throw(400, '不能下载文件夹');
      }
      
      const filename = path.basename(fullPath);
      const mimeType = mime.lookup(filename) || 'application/octet-stream';
      
      ctx.set('Content-Type', mimeType);
      ctx.set('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`);
      ctx.set('Content-Length', stats.size);
      
      ctx.body = fs.createReadStream(fullPath);
    } catch (err) {
      ctx.throw(500, `下载文件失败: ${err.message}`);
    }
  }

  // 移动/重命名文件或文件夹
  static async moveFile(ctx) {
    const { from, to } = ctx.request.body;
    
    if (!from || !to) {
      ctx.throw(400, '请提供源路径和目标路径');
    }
    
    if (!validatePath(from) || !validatePath(to)) {
      ctx.throw(400, '非法路径');
    }
    
    // 安全路径构建
    const { path: fromPath, safe: safe1 } = safePath(config.storage.path, from);
    const { path: toPath, safe: safe2 } = safePath(config.storage.path, to);
    
    if (!safe1 || !safe2) {
      ctx.throw(400, '无效的路径');
    }
    
    try {
      // 检查源文件是否存在
      const stats = await fs.stat(fromPath);
      
      // 确保目标目录存在
      const toDir = path.dirname(toPath);
      await fs.ensureDir(toDir);
      
      await fs.move(fromPath, toPath);
      ctx.body = {
        success: true,
        message: '移动成功',
        data: {
          from: from,
          to: to
        }
      };
    } catch (err) {
      ctx.throw(500, `移动失败: ${err.message}`);
    }
  }

  // 获取文件信息
  static async getFileInfo(ctx) {
    const relativePath = ctx.query.path;
    
    if (!relativePath) {
      ctx.throw(400, '请指定文件路径');
    }
    
    if (!validatePath(relativePath)) {
      ctx.throw(400, '非法路径');
    }
    
    // 安全路径构建
    const { path: fullPath, safe } = safePath(config.storage.path, relativePath);
    if (!safe) {
      ctx.throw(400, '无效的路径');
    }
    
    try {
      const stats = await fs.stat(fullPath);
      
      ctx.body = {
        success: true,
        data: {
          name: path.basename(fullPath),
          path: relativePath,
          type: stats.isDirectory() ? 'folder' : 'file',
          size: stats.size,
          created: stats.birthtime,
          modified: stats.mtime,
          mimeType: stats.isDirectory() ? null : mime.lookup(fullPath) || 'application/octet-stream'
        }
      };
    } catch (err) {
      ctx.throw(500, `获取文件信息失败: ${err.message}`);
    }
  }
}

module.exports = FileController; 